//
// Created by Win on 2015/11/27.
//
#include <stdio.h>
#include <sys/time.h>

#include "frct_comm.h"
#include "corba_core.h"
#include "corba_comm.h"
#include "wls_parse_message.h"

extern void *g_p_apm_context;

/*!
 * 网络大头字节序转本地字节序
 */
#define pntohi(p)  ((unsigned int)*((const unsigned char *)(p + 0)) << 24 | \
                    (unsigned int)*((const unsigned char *)(p + 1)) << 16 | \
                    (unsigned int)*((const unsigned char *)(p + 2)) << 8 | \
                    (unsigned int)*((const unsigned char *)(p + 3)) << 0)

/*!
 * 网络小头字节序转本地字节序
 */
#define pn2hi(p)  ((unsigned int)*((const unsigned char *)(p + 3)) << 24 | \
                    (unsigned int)*((const unsigned char *)(p + 2)) << 16 | \
                    (unsigned int)*((const unsigned char *)(p + 1)) << 8 | \
                    (unsigned int)*((const unsigned char *)(p + 0)) << 0)


/*!
 * 判断是否是 CORBA 协议
 *
 * \p_st_conn                    (输入数据信息)
 * \p_st_packet                 (输入数据)
 *
 * \return APM_L7_IS_NO:不属于TCP协议\n
 *         APM_L7_IS_YES:属于TCP协议
 *
 */
int corba_detect(Conntrack *p_st_conn, Apm_packet *p_st_packet)
{
    int i_ret = 0;
    char *p_data_in = NULL;
    int i_data_len = 0, i_mess_size = 0, is_little_endian = 0;
    int i_mess_type = 0; //00: request    01: reply

    if(p_st_conn == NULL || p_st_packet == NULL || p_st_packet->p_payload == NULL || p_st_packet->ui_payload_len <= 4)
        return APM_L7_IS_NO;

    p_data_in = p_st_packet->p_payload;
    i_data_len = p_st_packet->ui_payload_len;

    if(memcmp(p_data_in, "GIOP", 4) != 0)
        return APM_L7_IS_NO;

    p_data_in += 4;
    i_data_len -= 4;

    if(i_data_len < 8)
        return APM_L7_IS_NO;

    //version  字节序   message_type
    p_data_in += 2;
    i_data_len -= 2;

    is_little_endian = (*p_data_in) & 0x01;
    p_data_in++;
    i_data_len--;

    i_mess_type = (int)*p_data_in;
    p_data_in++;
    i_data_len--;

    if(is_little_endian)
        i_mess_size = pn2hi(p_data_in);
    else
        i_mess_size = pntohi(p_data_in);

    i_data_len -= 4;

    //数据包内容大于所描述的长度
    if(i_data_len > i_mess_size)
        return APM_L7_IS_NO;

    i_ret = frct_get_direct_known(p_st_conn);
    if(i_ret == FR_DIRECT_KNOWN)
        return APM_L7_IS_YES;

    //方向设定
    if(i_mess_type == 1 || i_mess_type == 4)
        frcap_set_cs_srv(p_st_conn, p_st_packet->src_ip, p_st_packet->src_port);
    else
    {
        if (frmemstr(p_data_in, i_data_len, (char *)WEBLOGIC_JMS_PUSHREQUEST, strlen(WEBLOGIC_JMS_PUSHREQUEST)) != NULL)
            frcap_set_cs_srv(p_st_conn, p_st_packet->src_ip, p_st_packet->src_port);
        else if(i_mess_type == 0 || i_mess_type == 2 || i_mess_type == 3)
            frcap_set_cs_srv(p_st_conn, p_st_packet->dst_ip, p_st_packet->dst_port);
        else
            return APM_L7_IS_NO;
    }

    return APM_L7_IS_YES;

}

FR_STATIC corba_session* __corba_session_create(void)
{
    corba_session *p_corba_session_private = NULL;

    p_corba_session_private = (corba_session *)frmalloc(sizeof(corba_session));
    if(p_corba_session_private == NULL)
        return NULL;

    memset(p_corba_session_private, 0x00, sizeof(corba_session));

    p_corba_session_private->p_st_data = bytebuff_creat();
    if(p_corba_session_private->p_st_data == NULL)
        return NULL;

    return p_corba_session_private;

}

/*!
 * session 数据内存分配
 *
 * \
 *
 * \return NULL: 失败\n
 *         p_st_private: 成功\n
 */
FR_STATIC L7session_corba_private* __corba_private_create(void)
{
    L7session_corba_private *p_st_private = NULL;

    p_st_private = (L7session_corba_private *)frmalloc(sizeof(L7session_corba_private));
    if(p_st_private == NULL)
        return NULL;

    memset(p_st_private, 0x00, sizeof(L7session_corba_private));

    return p_st_private;
}

/*!
 * session 数据初始化
 *
 * \p_st_private        （L7session_corba_private*）
 *
 * \return FR_FAIL: 失败\n
 *         FR_SUCC: 成功\n
 */
FR_STATIC int __corba_private_destroy(L7session_corba_private **pp_st_private)
{
    L7session_corba_private *p_st_private = NULL;

    if(pp_st_private == NULL)
        return FR_FAIL;

    p_st_private = *pp_st_private;

    if(p_st_private)
    {
        if(p_st_private->p_st_body_data_req)
            frreport_body_free(&p_st_private->p_st_body_data_req);

        if(p_st_private->p_st_body_data_resp)
            frreport_body_free(&p_st_private->p_st_body_data_resp);

        if(p_st_private->p_lst_comm_tmp)
            frreport_body_l7list_free(&p_st_private->p_lst_comm_tmp);

        if(p_st_private->p_lst_req_tmp)
            frreport_body_l7list_free(&p_st_private->p_lst_req_tmp);

        if(p_st_private->p_lst_mq_tmp)
            frreport_body_l7list_free(&p_st_private->p_lst_mq_tmp);

        if(p_st_private->p_server)
            frfree(p_st_private->p_server);

        if(p_st_private->p_title)
            frfree(p_st_private->p_title);

        frfree(p_st_private);

        *pp_st_private = NULL;
    }

    return FR_SUCC;

}



FR_STATIC int corba_session_reset(corba_session *p_corba_session_private)
{
    if(p_corba_session_private == NULL)
        return FR_FAIL;

    bytebuff_truncate(p_corba_session_private->p_st_data);

    memset(&p_corba_session_private->st_l4_trans, 0x00, sizeof(L4_transaction));

    p_corba_session_private->i_data_len = 0;

    return FR_SUCC;

}

FR_STATIC int __push_session_private(corba_session *p_session_private)
{
    Frlist_node *p_st_node = NULL;

    if(p_session_private == NULL || p_session_private->p_st_private == NULL)
        return FR_FAIL;

    p_st_node = frlist_node_create(p_session_private->p_st_private);
    if(p_st_node == NULL)
        return FR_FAIL;

    p_session_private->p_st_private = NULL;

    frlist_add_tail(&p_session_private->st_private, p_st_node);

    return FR_SUCC;

}

/*!
 * session信息添加
 *
 * \
 */
FR_STATIC int __add_jms_session(Frreport_body_data *p_st_body_data, Wls_jms_info *p_st_jms)
{
    Wls_jms_session *p_st_jms_session = NULL;
    int i_ret = 0;

    if (p_st_body_data == NULL || p_st_jms == NULL || p_st_jms->p_st_session == NULL)
        return FR_FAIL;

    p_st_jms_session = p_st_jms->p_st_session;

    // 队列名
    if (p_st_jms_session->p_queue != NULL)
    {
        if (p_st_jms->is_topic == 1)
            i_ret = frreport_body_l7_add_str(p_st_body_data, WLS_REPORT_KEY_TOPIC, p_st_jms_session->p_queue);
        else
            i_ret = frreport_body_l7_add_str(p_st_body_data, WLS_REPORT_KEY_QUEUE, p_st_jms_session->p_queue);
    }

    // weblogic server
    if (p_st_jms_session->p_jms_server != NULL)
    {
        i_ret = frreport_body_l7_add_str(p_st_body_data, WLS_REPORT_KEY_WEBL_JMS_SERVER, p_st_jms_session->p_jms_server);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }

    // weblogic jms module
    if (p_st_jms_session->p_jms_module != NULL)
    {
        i_ret = frreport_body_l7_add_str(p_st_body_data, WLS_REPORT_KEY_WEBL_JMS_MODULE, p_st_jms_session->p_jms_module);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }

    return FR_SUCC;
}


FR_STATIC void __was_info_reset(corba_session *p_st_corba_session)
{
    if (p_st_corba_session == NULL)
        return;

    if (p_st_corba_session->p_key_address)
        frfree(p_st_corba_session->p_key_address);

    if (p_st_corba_session->p_was_function)
        frfree(p_st_corba_session->p_was_function);

    p_st_corba_session->p_key_address = NULL;
    p_st_corba_session->p_was_function = NULL;
    p_st_corba_session->i_key_addr_len = 0;

    return;
}

/*!
 * corba req 数据解析
 *
 * \
 */
FR_STATIC int __corba_req_analysis(Conntrack *p_st_conn, Apm_packet *p_st_packet
                                 , Frhash_header *p_st_hash_report, L7_session *p_st_session)
{
    int i_ret = 0;
    L7session_corba_private *p_st_private = NULL;
    corba_session *p_session_private = NULL;
    L4_transaction *p_st_l4_trans = NULL;
    Frreport_data *p_st_report_data = NULL;
    Wls_jms_info *p_st_jms = NULL;
    unsigned long ul_tmp = 0;

    if(p_st_conn == NULL || p_st_packet == NULL || p_st_hash_report == NULL || p_st_session == NULL)
        return APM_L7_ANALYZE_FAIL;

    //session 数据获取
    p_session_private = (corba_session*)frct_get_session_private(p_st_session);
    if(p_session_private == NULL)
    {
        p_st_session->p_session_private = __corba_session_create();
        if(p_st_session->p_session_private == NULL)
            return APM_L7_ANALYZE_FAIL;

        p_session_private =(corba_session *)p_st_session->p_session_private;

        fruuid(p_session_private->arr_session_id);

    }

    if(p_session_private->p_st_private == NULL)
    {
        p_session_private->p_st_private = __corba_private_create();
        if(p_session_private->p_st_private == NULL)
            return APM_L7_ANALYZE_FAIL;
    }

    p_st_private = p_session_private->p_st_private;
    p_st_l4_trans = &p_st_private->st_l4_trans;

    i_ret = bytebuff_add(p_session_private->p_st_data, p_st_packet->p_payload, p_st_packet->ui_payload_len);
    if(i_ret == FR_FAIL)
        return APM_L7_ANALYZE_FAIL;

ANALYSIS:

    //first byte
    if(p_st_l4_trans->st_request_time_first_byte.tv_sec == 0)
    {
        //st_request_time_first_byte
        p_st_l4_trans->st_request_time_first_byte.tv_sec = p_st_packet->st_timestamp.tv_sec;
        p_st_l4_trans->st_request_time_first_byte.tv_usec = p_st_packet->st_timestamp.tv_usec;

        //seq
        p_st_private->ul_seq = frct_seq_increase(p_st_conn);

        //
        p_st_private->p_st_body_data_req = frreport_body_new_l7(p_st_conn);
        if(p_st_private->p_st_body_data_req == NULL)
            return APM_L7_ANALYZE_FAIL;
    }

    /* 请求的字节数 */
    p_st_l4_trans->l_request_bytes += p_st_packet->ui_payload_len;

    i_ret = corba_request_parse(p_session_private->p_st_data, p_st_private->p_st_body_data_req, p_session_private);
    if(i_ret != APM_L7_ANALYZE_SUCC)
    {
        bytebuff_rewind(p_session_private->p_st_data);
        return i_ret;
    }

    if(p_st_private->i_message_type == 3)
    {
        frreport_body_free (&p_st_private->p_st_body_data_req);

        bytebuff_free(&p_session_private->p_st_data);
        p_session_private->p_st_data = bytebuff_creat();
        if(p_session_private->p_st_data == NULL)
            return APM_L7_ANALYZE_FAIL;

        p_session_private->i_data_len = 0;

        __corba_private_destroy(&p_session_private->p_st_private);

        if (p_session_private->p_wls_function)
            frfree(p_session_private->p_wls_function);
        p_session_private->p_wls_function = NULL;

        return APM_L7_ANALYZE_SET_REQ (APM_L7_ANALYZE_SUCC);
    }
    else if(p_st_private->i_message_type == 7)
    {
        bytebuff_truncate(p_session_private->p_st_data);
        if(p_session_private->p_st_data->ui_remaining)
            goto ANALYSIS;

        __corba_private_destroy(&p_session_private->p_st_private);
        return APM_L7_ANALYZE_SET_RESP (APM_L7_ANALYZE_SUCC);
    }

    //st_request_time
    p_st_l4_trans->st_request_time.tv_sec = p_st_packet->st_timestamp.tv_sec;
    p_st_l4_trans->st_request_time.tv_usec = p_st_packet->st_timestamp.tv_usec;

    //ct
    i_ret = frreport_body_l7_add_connInfo(p_st_private->p_st_body_data_req, p_st_conn);
    if(i_ret == FR_FAIL)
        return APM_L7_ANALYZE_FAIL;

    //信息上报

    //title
    if(frreport_body_l7_add_str(p_st_private->p_st_body_data_req, APM_REPORT_KEY_TRANS_TITLE, p_st_private->p_title) == FR_FAIL)
    goto ERROR;

    if (p_session_private->is_wls_ejb == 0 && p_session_private->is_wls_jms == 0
        && p_session_private->is_was_ejb == 0)
    {
        //function
        if(frreport_body_l7_add_str(p_st_private->p_st_body_data_req, "request.rpc.function", p_st_private->p_title) == FR_FAIL)
            goto ERROR;
    }

    //server
    if(frreport_body_l7_add_str(p_st_private->p_st_body_data_req, APM_REPORT_KEY_SESSION_SERVER, p_st_private->p_server) == FR_FAIL)
        goto ERROR;

    if(frreport_body_l7_add_str(p_st_private->p_st_body_data_req, APM_REPORT_KEY_SESSION_ID, p_session_private->arr_session_id) == FR_FAIL)
        goto ERROR;

    if(frreport_body_l7_add_ulong(p_st_private->p_st_body_data_req, APM_REPORT_KEY_REQ_ID, p_st_private->ul_seq) == FR_FAIL)
        goto ERROR;

    if(frreport_body_l7_add_timeval(p_st_private->p_st_body_data_req, APM_REPORT_KEY_REQ_START_TIMESTAMP, &p_st_l4_trans->st_request_time_first_byte) == FR_FAIL)
        goto ERROR;

    if(frreport_body_l7_add_timeval(p_st_private->p_st_body_data_req, APM_REPORT_KEY_REQ_END_TIMESTAMP, &p_st_l4_trans->st_request_time) == FR_FAIL)
        goto ERROR;

    ul_tmp = frtime_diff(&p_st_l4_trans->st_request_time_first_byte, &p_st_l4_trans->st_request_time);
    if(frreport_body_l7_add_ulong(p_st_private->p_st_body_data_req, APM_REPORT_KEY_REQ_SEND_TIME_US, ul_tmp) == FR_FAIL)
        goto ERROR;

    if(frreport_body_l7_add_long(p_st_private->p_st_body_data_req, APM_REPORT_KEY_REQ_DATA_BYTES, p_st_l4_trans->l_request_bytes) == FR_FAIL)
        goto ERROR;

    //i_response_required APM_REPORT_KEY_REQ_ISRESPREQUIRED
    if(p_st_private->i_version != 2)
    {
        if(frreport_body_l7_add_int(p_st_private->p_st_body_data_req, APM_REPORT_KEY_REQ_ISRESPREQUIRED, p_st_private->i_response_required) == FR_FAIL)
            goto ERROR;
    }
    else
    {
        if(p_st_private->i_message_type != 1)
        {
            if(frreport_body_l7_add_int(p_st_private->p_st_body_data_req, APM_REPORT_KEY_REQ_ISRESPREQUIRED, 1) == FR_FAIL)
                goto ERROR;
        }
        else
        {
            if(frreport_body_l7_add_int(p_st_private->p_st_body_data_req, APM_REPORT_KEY_REQ_ISRESPREQUIRED, 0) == FR_FAIL)
                goto ERROR;
        }
    }

    //body data
    if (p_session_private->is_wls_jms == 1)
    {
        p_st_jms = p_session_private->p_st_jms;
        if (p_st_jms == NULL)
            goto ERROR;

        //客户端发起的响应不需要添加session
        if (p_st_private->i_message_type != 1)
        {
            if (__add_jms_session(p_st_private->p_st_body_data_req, p_st_jms) == FR_FAIL)
                goto ERROR;
        }

        if (p_st_jms->i_type == WLS_SUB)
            p_st_report_data = frreport_data_l7_new(FRREPORT_TYPE_L7DATA_SUB);
        else
            p_st_report_data = frreport_data_l7_new(FRREPORT_TYPE_L7DATA_REQ);

        p_st_jms->i_type = WLS_PTOP; // 初期化
    }
    else
        p_st_report_data = frreport_data_l7_new(FRREPORT_TYPE_L7DATA_REQ);

    p_st_private->p_lst_comm_tmp = FRREPORT_BODY_L7LIST_CLONE_COMM(p_st_private->p_st_body_data_req);
    if(p_st_private->p_lst_comm_tmp == NULL)
        goto ERROR;

    p_st_private->p_lst_req_tmp = FRREPORT_BODY_L7LIST_CLONE_REQ(p_st_private->p_st_body_data_req);
    if(p_st_private->p_lst_req_tmp == NULL)
        goto ERROR;

    p_st_private->p_lst_mq_tmp = FRREPORT_BODY_L7LIST_CLONE_MQ(p_st_private->p_st_body_data_req);

    if(frreport_data_add_body(p_st_report_data, p_st_private->p_st_body_data_req) == FR_FAIL)
        goto ERROR;
    p_st_private->p_st_body_data_req = NULL;

    if(frreport_data_hash(p_st_hash_report, p_st_report_data) == FR_FAIL)
        goto ERROR;

    bytebuff_free(&p_session_private->p_st_data);
    p_session_private->p_st_data = bytebuff_creat();
    if(p_session_private->p_st_data == NULL)
        return APM_L7_ANALYZE_FAIL;

    p_session_private->i_data_len = 0;

    //客户端发起的响应
    if(p_st_private->i_message_type == 1)
    {
        __corba_private_destroy(&p_session_private->p_st_private);
        __was_info_reset(p_session_private);
        if (p_session_private->p_wls_function)
            frfree(p_session_private->p_wls_function);
        p_session_private->p_wls_function = NULL;
        return APM_L7_ANALYZE_SET_REQ(APM_L7_ANALYZE_SUCC);
    }

    i_ret = __push_session_private(p_session_private);
    if(i_ret == FR_FAIL)
        return APM_L7_ANALYZE_FAIL;

    if (p_session_private->p_wls_function)
        frfree(p_session_private->p_wls_function);
    p_session_private->p_wls_function = NULL;

    return APM_L7_ANALYZE_SET_REQ(APM_L7_ANALYZE_SUCC);

ERROR:
    if (p_st_private->p_st_body_data_req)
        frreport_body_free(&p_st_private->p_st_body_data_req);

    if(p_st_report_data)
        frreport_data_free(&p_st_report_data);

    if(p_st_private->p_lst_comm_tmp)
        frreport_body_l7list_free(&p_st_private->p_lst_comm_tmp);

    if(p_st_private->p_lst_req_tmp)
        frreport_body_l7list_free(&p_st_private->p_lst_req_tmp);

    if(p_st_private->p_lst_mq_tmp)
        frreport_body_l7list_free(&p_st_private->p_lst_mq_tmp);

    return APM_L7_ANALYZE_FAIL;

}

/*!
 * corba resp 数据解析
 *
 * \
 */
FR_STATIC int __corba_resp_analysis(Conntrack *p_st_conn, Apm_packet *p_st_packet
                                  , Frhash_header *p_st_hash_report, L7_session *p_st_session)
{
    int i_ret = 0;
    L7session_corba_private *p_st_private = NULL;
    corba_session *p_session_private = NULL;
    L4_transaction *p_st_l4_trans = NULL;
    L4_transaction *p_st_l4_trans_req = NULL;
    Frreport_data *p_st_report_data = NULL;
    Wls_jms_info *p_st_jms = NULL;
    unsigned long ul_tmp = 0;

    if(p_st_conn == NULL || p_st_packet == NULL || p_st_hash_report == NULL || p_st_session == NULL)
        return APM_L7_ANALYZE_FAIL;

    //session 数据获取
    p_session_private = (corba_session*)frct_get_session_private(p_st_session);
    if(p_session_private == NULL)
    {
        p_st_session->p_session_private = __corba_session_create();
        if(p_st_session->p_session_private == NULL)
            return APM_L7_ANALYZE_FAIL;

        p_session_private =(corba_session *)p_st_session->p_session_private;

        fruuid(p_session_private->arr_session_id);
     }

    p_st_l4_trans = &p_session_private->st_l4_trans;

    //first byte
    if(p_st_l4_trans->st_response_time_first_byte.tv_sec == 0)
    {
        //st_response_time_first_byte
        p_st_l4_trans->st_response_time_first_byte.tv_sec = p_st_packet->st_timestamp.tv_sec;
        p_st_l4_trans->st_response_time_first_byte.tv_usec = p_st_packet->st_timestamp.tv_usec;

    }

    p_st_l4_trans->l_response_bytes += p_st_packet->ui_payload_len;

    i_ret = bytebuff_add(p_session_private->p_st_data, p_st_packet->p_payload, p_st_packet->ui_payload_len);
    if(i_ret == FR_FAIL)
        return APM_L7_ANALYZE_FAIL;

ANALYSIS:
    // get p_st_private
    if(p_session_private->p_st_private == NULL)
    {
        i_ret = giop_get_private(p_session_private->p_st_data, p_session_private);
        if(i_ret == FR_FAIL)
        {
            bytebuff_rewind(p_session_private->p_st_data);
            return APM_L7_ANALYZE_TODO;
        }

        bytebuff_rewind(p_session_private->p_st_data);
        if(p_session_private->p_st_private == NULL)
            p_session_private->p_st_private = __corba_private_create();

        //
        p_st_private = p_session_private->p_st_private;

        //seq
        if(p_st_private->ul_seq == 0)
            p_st_private->ul_seq = frct_seq_increase(p_st_conn);

        p_st_private->p_st_body_data_resp = frreport_body_new_l7(p_st_conn);
        if(p_st_private->p_st_body_data_resp == NULL)
            return APM_L7_ANALYZE_FAIL;

    }

    p_st_private = p_session_private->p_st_private;
    p_st_l4_trans_req = &p_st_private->st_l4_trans;

    i_ret = corba_response_parse(p_session_private->p_st_data, p_st_private->p_st_body_data_resp, p_session_private);
    if(i_ret != APM_L7_ANALYZE_SUCC)
    {
        bytebuff_rewind(p_session_private->p_st_data);
        return i_ret;
    }

    if(p_st_private->i_message_type == 4)
    {
        __corba_private_destroy(&p_session_private->p_st_private);
        __was_info_reset(p_session_private);
        if (p_session_private->p_wls_function)
            frfree(p_session_private->p_wls_function);
        p_session_private->p_wls_function = NULL;

        return APM_L7_ANALYZE_SET_RESP (APM_L7_ANALYZE_SUCC);
    }
    else if(p_st_private->i_message_type == 7)
    {
        bytebuff_truncate(p_session_private->p_st_data);
        if(p_session_private->p_st_data->ui_remaining)
            goto ANALYSIS;

        __corba_private_destroy(&p_session_private->p_st_private);

        return APM_L7_ANALYZE_SET_RESP (APM_L7_ANALYZE_SUCC);
    }




    if(p_st_l4_trans_req->st_request_time.tv_sec)
        ul_tmp = frtime_diff(&p_st_l4_trans_req->st_request_time, &p_st_l4_trans->st_response_time_first_byte);
    else
        ul_tmp = 0;

    if(frreport_body_l7_add_ulong(p_st_private->p_st_body_data_resp, APM_REPORT_KEY_RESP_SERVER_TIME_US, ul_tmp) == FR_FAIL)
        goto ERROR;

    if(p_st_private->p_lst_comm_tmp)
    {
        //comm
        if(FRREPORT_BODY_L7LIST_SET_COMM(p_st_private->p_st_body_data_resp, &p_st_private->p_lst_comm_tmp) == FR_FAIL)
            goto ERROR;

        //把req数据链表添加到resp中
        if(FRREPORT_BODY_L7LIST_SET_REQ(p_st_private->p_st_body_data_resp, &p_st_private->p_lst_req_tmp) == FR_FAIL)
            goto ERROR;

        if (p_st_private->p_lst_mq_tmp)
        {
            //把req数据链表添加到resp中
            if(FRREPORT_BODY_L7LIST_SET_MQ(p_st_private->p_st_body_data_resp, &p_st_private->p_lst_mq_tmp) == FR_FAIL)
                goto ERROR;
        }
    }
    else
    {
        if(frreport_body_l7_add_connInfo(p_st_private->p_st_body_data_resp, p_st_conn) == FR_FAIL)
            goto ERROR;

        if(frreport_body_l7_add_str(p_st_private->p_st_body_data_resp, APM_REPORT_KEY_SESSION_SERVER, p_st_private->p_server) == FR_FAIL)
            goto ERROR;

        if(frreport_body_l7_add_str(p_st_private->p_st_body_data_resp, APM_REPORT_KEY_SESSION_ID, p_session_private->arr_session_id) == FR_FAIL)
            goto ERROR;

        if(frreport_body_l7_add_str(p_st_private->p_st_body_data_resp, APM_REPORT_KEY_TRANS_TITLE, p_st_private->p_title) == FR_FAIL)
            goto ERROR;
    }

    p_st_l4_trans->st_response_time.tv_sec = p_st_packet->st_timestamp.tv_sec;
    p_st_l4_trans->st_response_time.tv_usec = p_st_packet->st_timestamp.tv_usec;

    if(frreport_body_l7_add_timeval(p_st_private->p_st_body_data_resp, APM_REPORT_KEY_RESP_START_TIMESTAMP, &p_st_l4_trans->st_response_time_first_byte) == FR_FAIL)
        goto ERROR;

    if(frreport_body_l7_add_timeval(p_st_private->p_st_body_data_resp, APM_REPORT_KEY_RESP_END_TIMESTAMP, &p_st_l4_trans->st_response_time) == FR_FAIL)
        goto ERROR;

    ul_tmp = frtime_diff(&p_st_l4_trans->st_response_time_first_byte, &p_st_l4_trans->st_response_time);
    if(frreport_body_l7_add_ulong(p_st_private->p_st_body_data_resp, APM_REPORT_KEY_RESP_DOWNLOAD_TIME_US, ul_tmp) == FR_FAIL)
        goto ERROR;

    if(frreport_body_l7_add_long(p_st_private->p_st_body_data_resp, APM_REPORT_KEY_RESP_DATA_BYTES, p_st_l4_trans->l_response_bytes) == FR_FAIL)
        goto ERROR;

    if(frreport_body_l7_add_long(p_st_private->p_st_body_data_resp, APM_REPORT_KEY_RESP_CODE, p_st_private->l_response_code) == FR_FAIL)
        goto ERROR;

    if (p_session_private->is_wls_jms == 1)
    {
        p_st_jms = p_session_private->p_st_jms;
        if (p_st_jms == NULL)
            goto ERROR;

        // 服务器发起的请求
        if (p_st_private->i_message_type == 0)
        {
            if (__add_jms_session(p_st_private->p_st_body_data_resp, p_st_jms) == FR_FAIL)
                goto ERROR;
        }

        if (p_st_jms->i_type == WLS_NOTIFY)
            p_st_report_data = frreport_data_l7_new(FRREPORT_TYPE_L7DATA_NOTIFY);
        else
            p_st_report_data = frreport_data_l7_new(FRREPORT_TYPE_L7DATA_RESP);

        p_st_jms->i_type = WLS_PTOP; // 初期化
    }
    else
        p_st_report_data = frreport_data_l7_new(FRREPORT_TYPE_L7DATA_RESP);

    if(p_st_report_data == NULL)
        goto ERROR;

    if(frreport_data_add_body(p_st_report_data, p_st_private->p_st_body_data_resp) == FR_FAIL)
        goto ERROR;
    p_st_private->p_st_body_data_resp = NULL;

    if(frreport_data_hash(p_st_hash_report, p_st_report_data) == FR_FAIL)
        goto ERROR;

    //服务器发起的请求,不释放
    if(p_st_private->i_message_type != 0
        || (p_session_private->p_wls_function != NULL && strcmp(p_session_private->p_wls_function, "dispatchOneWay") == 0))
    {
        __corba_private_destroy(&p_session_private->p_st_private);
        __was_info_reset(p_session_private);
        if (p_session_private->p_wls_function)
            frfree(p_session_private->p_wls_function);
        p_session_private->p_wls_function = NULL;
    }

    return APM_L7_ANALYZE_SET_RESP(APM_L7_ANALYZE_SUCC);


ERROR:
    if (p_st_private->p_st_body_data_resp)
        frreport_body_free(&p_st_private->p_st_body_data_resp);

    if(p_st_report_data)
        frreport_data_free(&p_st_report_data);

    return APM_L7_ANALYZE_FAIL;

}


int corba_analysis(Conntrack *p_st_conn, Apm_packet *p_st_packet, Frhash_header *p_st_hash_report)
{
    int i_ret = 0;
    L7_session *p_st_session = NULL;

    if(p_st_conn == NULL || p_st_packet == NULL || p_st_hash_report == NULL)
        return APM_L7_ANALYZE_FAIL;

    p_st_session = frct_get_session(p_st_conn);
    if(p_st_session == NULL)
        return APM_L7_ANALYZE_FAIL;

    if(p_st_packet->em_analyz_cmd == FRANALYZ_CMD_FIN || p_st_packet->em_analyz_cmd == FRANALYZ_CMD_SYN)
    {
        corba_session_destroy((void *)(p_st_session->p_session_private));
        p_st_session->p_session_private = NULL;
        return APM_L7_ANALYZE_SUCC;
    }

    //request
    if(p_st_packet->i_direction == FR_DIRECT_CLIENT2SRV)
    {
        i_ret = __corba_req_analysis(p_st_conn,p_st_packet,p_st_hash_report,p_st_session);
        if(i_ret == APM_L7_ANALYZE_FAIL)
            goto ERROR;

        return i_ret;
    }
    else//response
    {
        i_ret = __corba_resp_analysis(p_st_conn,p_st_packet,p_st_hash_report, p_st_session);
        if (i_ret == APM_L7_ANALYZE_FAIL)
            goto ERROR;

        if(i_ret & APM_L7_ANALYZE_SUCC)
        {
            if(corba_session_reset((corba_session*)p_st_session->p_session_private) == FR_FAIL)
                goto ERROR;
        }

        return i_ret;
    }

ERROR:
    corba_session_destroy(p_st_session->p_session_private);
    p_st_session->p_session_private = NULL;

    return APM_L7_ANALYZE_FAIL;
}


void corba_node_free(Frlist_node *p_st_node)
{
    if(p_st_node == NULL || p_st_node->data == NULL)
        return;

    __corba_private_destroy((L7session_corba_private**) &p_st_node->data);

    return;
}

void __jms_session_destroy(Wls_jms_session **pp_st_jms_session)
{
    Wls_jms_session *p_st_jms_session = NULL;

    p_st_jms_session = *pp_st_jms_session;

    if (p_st_jms_session == NULL)
        return;

    if (p_st_jms_session->p_queue)
        frfree(p_st_jms_session->p_queue);

    if (p_st_jms_session->p_title)
        frfree(p_st_jms_session->p_title);

    if (p_st_jms_session->p_weblogic_server)
        frfree(p_st_jms_session->p_weblogic_server);

    if (p_st_jms_session->p_jms_server)
        frfree(p_st_jms_session->p_jms_server);

    if (p_st_jms_session->p_jms_module)
        frfree(p_st_jms_session->p_jms_module);

    frfree(p_st_jms_session);

    return;
}

void __jms_info_destroy(Wls_jms_info **pp_st_jms)
{
    Wls_jms_info *p_st_jms = NULL;

    p_st_jms = *pp_st_jms;
    if (p_st_jms == NULL)
        return;

    if (p_st_jms->p_st_session)
        __jms_session_destroy(&p_st_jms->p_st_session);

    frfree(p_st_jms);

    return;
}

int corba_session_destroy(void *p_private_session)
{
    corba_session *p_session_private = (corba_session *)p_private_session;

    if (p_session_private != NULL)
    {
        if(p_session_private->p_st_data)
            bytebuff_free(&p_session_private->p_st_data);

        frlist_remove_all(&p_session_private->st_private, corba_node_free);

        if(p_session_private->p_st_private)
            __corba_private_destroy(&p_session_private->p_st_private);

        if (p_session_private->p_wls_ejbname)
            frfree(p_session_private->p_wls_ejbname);

        if (p_session_private->p_wls_function)
            frfree(p_session_private->p_wls_function);

        if (p_session_private->p_key_address)
            frfree(p_session_private->p_key_address);

        if (p_session_private->p_was_function)
            frfree(p_session_private->p_was_function);

        if (p_session_private->p_st_jms)
            __jms_info_destroy(&p_session_private->p_st_jms);

        frfree(p_session_private);
    }

    return FR_SUCC;
}
